local extension = Package("rfenghou_fuyao")
extension.extensionName = "aaa_fenghou"

local U = require "packages/utility/utility"

Fk:loadTranslationTable{
  ["rfenghou_fuyao"] = "扶摇",
  ["fuyao"] = "扶摇",
  ["fuyaoz"] = "扶摇",
}
Fk:appendKingdomMap("god", {"fuyao"})

local jisi = General(extension, "rfenghou__jisi", "fuyao", 4)
local baijiangdengwang = fk.CreateTriggerSkill{
  name = "rfenghou__baijiangdengwang",
  anim_type = "masochism",
  events = {fk.GameStart, fk.Damaged},
  can_trigger = function (self, event, target, player, data)
    if player:hasSkill(self) then
      if event == fk.GameStart then
        return true
      elseif event == fk.Damaged then
        return target == player
      end
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local existingGenerals = {}
    for _, p in ipairs(room.players) do
      table.insert(existingGenerals, p.general)
      table.insert(existingGenerals, p.deputyGeneral)
    end
    local generals = {}
    for name, general in pairs(Fk.generals) do
      if general.package.extensionName == "aaa_fenghou" and not table.contains(existingGenerals, name) and
        not general.hidden then
        table.insertIfNeed(generals, name)
      end
    end
    if #player:getTableMark(self.name) >= 15 then  --绷，好像没有获得子扩展包的简单方法
      for name, general in pairs(Fk.generals) do
        if general.package.name == "rfenghou_hall_of_fame" and not table.contains(existingGenerals, name) then
          table.insertIfNeed(generals, name)
        end
      end
    end
    generals = table.random(generals, 3)
    if #generals == 0 then return end
    local general = room:askForGeneral(player, generals, 1, true)
    local mark = player:getTableMark(self.name)
    table.insertIfNeed(mark, Fk.generals[general].package.name)
    room:setPlayerMark(player, self.name, mark)
    room:changeHero(player, general, false, true, true, false, false)
  end,
}
local fengqifuyao = fk.CreateTriggerSkill{
  name = "rfenghou__fengqifuyao$",
  anim_type = "special",
  events = {fk.Death},
  can_trigger = function(self, event, target, player, data)
    return player:hasSkill(self) and target.kingdom:startsWith("fuyao")
  end,
  on_cost = function (self, event, target, player, data)
    return player.room:askForSkillInvoke(player, self.name, nil, "#rfenghou__fengqifuyao-invoke:::"..target.general)
  end,
  on_use = function(self, event, target, player, data)
    player.room:changeHero(player, target.general, false, true, true, false, false)
  end,
}
jisi:addSkill(baijiangdengwang)
jisi:addSkill(fengqifuyao)
Fk:loadTranslationTable{
  ["rfenghou__jisi"] = "祭祀黄泉Romantic",
  ["#rfenghou__jisi"] = "萦名神亭",
  ["designer:rfenghou__jisi"] = "zzcclll朱苦力",
  --["illustrator:rfenghou__jisi"] = "",

  ["rfenghou__baijiangdengwang"] = "拜将登王",
  [":rfenghou__baijiangdengwang"] = "游戏开始时，或受到伤害后，你可以从“封侯”包中变更一次副将，所有势力的武将均变更过后，此后发现池中增加"..
  "荣誉室武将！",
  ["rfenghou__fengqifuyao"] = "风起扶摇",
  [":rfenghou__fengqifuyao"] = "主公技，“扶摇”势力的角色死亡时，你可以将其武将牌替换为你的副将。",
  ["#rfenghou__fengqifuyao-invoke"] = "风起扶摇：是否将副将变为 %arg？",
}

local zhukuli = General(extension, "rfenghou__zhukuli", "fuyaoz", 5)
local shejili = fk.CreateTriggerSkill{
  name = "rfenghou__shejili",
  anim_type = "support",
  frequency = Skill.Compulsory,
  events = {fk.CardUseFinished, fk.PreHpRecover, fk.PreCardEffect},
  can_trigger = function(self, event, target, player, data)
    if player:hasSkill(self) then
      if event == fk.CardUseFinished then
        if target == player and table.contains({"peach", "analeptic"}, data.card.trueName) and
          not table.contains(data.card.skillNames, self.name) and not player:isNude() then
          local name = data.card.trueName == "analeptic" and "peach" or "analeptic"
          return not player:prohibitUse(Fk:cloneCard(name)) and not player:isProhibited(player, Fk:cloneCard(name))
        end
      elseif event == fk.PreHpRecover then
        return target == player and data.num > (player.maxHp - player.hp)
      elseif event == fk.PreCardEffect then
        return data.to == player.id and table.contains({"peach", "god_salvation"}, data.card.trueName) and not player:isWounded()
        --一般而言不存在未受伤而回复体力的酒，所以偷懒！
      end
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    if event == fk.CardUseFinished then
      local name = data.card.trueName == "analeptic" and "peach" or "analeptic"
      local cards = table.filter(player:getCardIds("he"), function (id)
        local card = Fk:cloneCard(name)
        card.skillName = self.name
        card:addSubcard(id)
        return not player:prohibitUse(Fk:cloneCard(name)) and not player:isProhibited(player, Fk:cloneCard(name))
      end)
      if #cards > 0 then
        local id = room:askForCard(player, 1, 1, true, self.name, false, tostring(Exppattern{ id = cards }),
          "#rfenghou__shejili-ask:::"..name)
        local card = Fk:cloneCard(name)
        card.skillName = self.name
        card:addSubcards(id)
        local use = {
          card = card,
          from = player.id,
          tos = {{player.id}},
          extraUse = true,
        }
        if name == "analeptic" and player.dying then
          use.extra_data = {
            analepticRecover = true
          }
        end
        room:useCard(use)
      end
    else
      local n = 0
      if event == fk.PreHpRecover then
        n = data.num - (player.maxHp - player.hp)
      elseif event == fk.PreCardEffect then
        n = 1 + (data.additionalRecover or 0)
      end
      if n > 0 then
        local cards = room:getCardsFromPileByRule("slash,jink", n, "discardPile")
        if #cards > 0 then
          room:moveCardTo(cards, Card.PlayerHand, player, fk.ReasonJustMove, self.name, nil, true, player.id)
        end
      end
    end
  end,
}
local youxili = fk.CreateViewAsSkill{
  name = "rfenghou__youxili",
  anim_type = "control",
  pattern = "dismantlement",
  prompt = function ()
    return "#rfenghou__youxili:::"..(Self:getHandcardNum() - Self:getMaxCards())
  end,
  card_filter = function(self, to_select, selected)
    return Fk:currentRoom():getCardArea(to_select) == Card.PlayerHand and #selected < (Self:getHandcardNum() - Self:getMaxCards())
  end,
  view_as = function(self, cards)
    if #cards ~= (Self:getHandcardNum() - Self:getMaxCards()) then return end
    local c = Fk:cloneCard("dismantlement")
    c.skillName = self.name
    c:addSubcards(cards)
    return c
  end,
  enabled_at_play = function (self, player)
    return player:getHandcardNum() > player:getMaxCards() and player:usedSkillTimes(self.name, Player.HistoryRound) == 0
  end,
  enabled_at_response = function(self, player, response)
    return not response and player:getHandcardNum() > player:getMaxCards() and
      player:usedSkillTimes(self.name, Player.HistoryRound) == 0
  end,

  on_acquire = function (self, player, is_start)
    local room = player.room
    for _, p in ipairs(room:getOtherPlayers(player)) do
      room:handleAddLoseSkills(p, "rfenghou__youxili&", nil, false, true)
    end
  end,
  on_lose = function (self, player, is_death)
    local room = player.room
    if not table.find(room:getOtherPlayers(player), function (p)
      return p:hasSkill(self, true)
    end) then
      for _, p in ipairs(room:getOtherPlayers(player)) do
        room:handleAddLoseSkills(p, "-rfenghou__youxili&", nil, false, true)
      end
    end
  end,
}
local youxili_targetmod = fk.CreateTargetModSkill{
  name = "#rfenghou__youxili_targetmod",
  extra_target_func = function(self, player, skill, card)
    if card and skill.trueName == "dismantlement_skill" and table.contains(card.skillNames, "rfenghou__youxili") then
      return #card.subcards - 1
    end
  end,
}
local YouxiliFunc = function (player)
  return table.filter(Fk:currentRoom().alive_players, function (p)
    if p ~= player and p:hasSkill(youxili) and p:getMark("rfenghou__youxili-round") == 0 then
      local n = p:getMaxCards() - p:getHandcardNum()
      return n > 0 and player:getHandcardNum() >= n
    end
  end)
end
local youxili_viewas = fk.CreateViewAsSkill{
  name = "rfenghou__youxili&",
  pattern = "nullification",
  prompt = function (self, selected_cards, selected)
    local src = YouxiliFunc(Self)
    if #src > 0 then
      return "#rfenghou__youxili&:"..src[1].id.."::"..(src[1]:getMaxCards() - src[1]:getHandcardNum())
    end
  end,
  card_filter = function (self, to_select, selected)
    return table.find(YouxiliFunc(Self), function (p)
      return #selected < p:getMaxCards() - p:getHandcardNum()
    end)
  end,
  view_as = function(self, cards)
    if not table.find(YouxiliFunc(Self), function (p)
      return #cards == p:getMaxCards() - p:getHandcardNum()
    end) then return end
    self.cost_data = cards
    local card = Fk:cloneCard("nullification")
    card.skillName = self.name
    return card
  end,
  before_use = function (self, player, use)
    local room = player.room
    local to
    local targets = table.filter(YouxiliFunc(Self), function (p)
      return #self.cost_data == p:getMaxCards() - p:getHandcardNum()
    end)
    if #targets == 1 then
      to = targets[1]
    elseif #targets > 1 then
      to = room:askForChoosePlayers(player, table.map(targets, Util.IdMapper), 1, 1, "#rfenghou__youxili-give", self.name, false)
    end
    if to then
      room:setPlayerMark(to, "rfenghou__youxili-round", 1)
      room:moveCardTo(self.cost_data, Card.PlayerHand, to, fk.ReasonGive, self.name, nil, false, player.id)
    else
      return self.name
    end
  end,
  enabled_at_play = Util.FalseFunc,
  enabled_at_response = function (self, player, response)
    return not response and #YouxiliFunc(player) > 0
  end,
}
Fk:addSkill(youxili_viewas)
youxili:addRelatedSkill(youxili_targetmod)
zhukuli:addSkill(shejili)
zhukuli:addSkill(youxili)
Fk:loadTranslationTable{
  ["rfenghou__zhukuli"] = "朱苦力",
  ["#rfenghou__zhukuli"] = "猪",
  ["designer:rfenghou__zhukuli"] = "秀丽",
  --["illustrator:rfenghou__zhukuli"] = "",

  ["rfenghou__shejili"] = "超绝设计力",
  [":rfenghou__shejili"] = "锁定技，你未因此使用【桃】或【酒】后，须将一张牌当另一张使用；你能溢出上限回复体力，且改为获得弃牌堆中等量的"..
  "【杀】或【闪】。",
  ["rfenghou__youxili"] = "超强游戏力",
  [":rfenghou__youxili"] = "每轮各限一次，其他角色可以交给你能补至手牌上限张的手牌，以视为使用【无懈可击】；你可以将溢出手牌上限的手牌"..
  "当指定至多等量目标数的【过河拆桥】使用。",
  ["#rfenghou__shejili-ask"] = "超绝设计力：你需将一张牌当【%arg】使用",
  ["rfenghou__youxili&"] = "超强游戏力",
  [":rfenghou__youxili&"] = "每轮所有角色限一次，你可以交给朱苦力手牌使其手牌补至手牌上限，以视为使用【无懈可击】。",
  ["#rfenghou__youxili"] = "超强游戏力：你可以将%arg张手牌当指定至多等量目标的【过河拆桥】使用",
  ["#rfenghou__youxili&"] = "超强游戏力：你可以交给 %src %arg张手牌以视为使用【无懈可击】",
}

local yidaju = General(extension, "rfenghou__yidaju", "fuyao", 4)
local dajiaohuan = fk.CreateTriggerSkill{
  name = "rfenghou__dajiaohuan",
  events = {fk.EventPhaseStart},
  anim_type = "offensive",
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(self) and player.phase > 1 and player.phase < 8
  end,
  on_use = function (self, event, target, player, data)
    local room = player.room
    local judge = {
      who = target,
      reason = self.name,
      pattern = ".|.|spade,club,diamond",
    }
    room:judge(judge)
    if judge.card.suit == Card.Heart then
      player:chat("啊啊啊啊啊啊啊啊啊啊！")
    else
      local card = {room.draw_pile[1]}
      if #card > 0 then
        U.askForUseRealCard(room, player, card, nil, self.name,
          "#rfenghou__dajiaohuan-use", {
            bypass_times = true,
            extraUse = true,
            expand_pile = card,
          }, false, true)
      end
    end
  end,
}
for i = 1, 10, 1 do
  local yidaju_ = General(extension, "rfenghou"..i.."_yidaju", "fuyao", 4)
  yidaju_.total_hidden = true
end
local lianxuju = fk.CreateTriggerSkill{
  name = "rfenghou__lianxuju",
  anim_type = "control",
  events = {fk.TurnEnd},
  can_trigger = function(self, event, target, player, data)
    if target == player and player:hasSkill(self) then
      local room = player.room
      local dat = {}
      room.logic:getEventsOfScope(GameEvent.Phase, 1, function (e)
        if e.data[1] == player then
          table.insert(dat, {e.id, e.end_id})
        end
      end, Player.HistoryTurn)
      if #dat == 0 then return end
      local n = 0
      for _, info in ipairs(dat) do
        if #room.logic:getEventsOfScope(GameEvent.UseCard, 1, function (e)
          return e.id >= info[1] and e.id <= info[2] and e.data[1].from == player.id
        end, Player.HistoryTurn) > 0 then
          n = n + 1
        end
      end
      if n > 0 then
        self.cost_data = n
        return true
      end
    end
  end,
  on_cost = function (self, event, target, player, data)
    local room = player.room
    local n = self.cost_data
    local tos = room:askForChoosePlayers(player, table.map(room.alive_players, Util.IdMapper), 1, n,
      "#rfenghou__lianxuju-choose:::"..n, self.name, true)
    if #tos > 0 then
      room:sortPlayersByAction(tos)
      self.cost_data = {tos = tos}
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    for _, id in ipairs(self.cost_data.tos) do
      local p = room:getPlayerById(id)
      p.general = "rfenghou"..math.random(1, 10).."_yidaju"
      room:broadcastProperty(p, "general")
      room:handleAddLoseSkills(p, "rfenghou__dajudao", nil, true, false)
    end
  end,
}
local dajudao = fk.CreateTriggerSkill{
  name = "rfenghou__dajudao",
  anim_type = "control",
  events = {fk.AskForRetrial},
  can_trigger = function(self, event, target, player, data)
    return player:hasSkill(self) and not player:isNude() and data.reason == "rfenghou__dajiaohuan"
  end,
  on_cost = function(self, event, target, player, data)
    local cards = player.room:askForCard(player, 1, 1, true, self.name, true, ".|.|spade,club",
      "#rfenghou__dajudao-ask::" .. target.id)
    if #cards == 1 then
      self.cost_data = {cards = cards}
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local card = Fk:getCardById(self.cost_data.cards[1])
    player.room:retrial(card, player, data, self.name, true)
  end,
}
yidaju:addSkill(dajiaohuan)
yidaju:addSkill(lianxuju)
yidaju:addRelatedSkill(dajudao)
Fk:loadTranslationTable{
  ["rfenghou__yidaju"] = "易大剧",
  ["#rfenghou__yidaju"] = "长恨离亭",
  ["designer:rfenghou__yidaju"] = "妙啊",
  --["illustrator:rfenghou__yidaju"] = "",

  ["rfenghou__dajiaohuan"] = "大叫唤",
  [":rfenghou__dajiaohuan"] = "阶段开始时，你进行一次判定，若结果不为<font color='red'>♥</font>，你可以使用牌堆顶的一张牌；"..
  "若结果为<font color='red'>♥</font>，你啊啊啊啊啊啊啊啊啊啊！",
  ["rfenghou__lianxuju"] = "连续剧",
  [":rfenghou__lianxuju"] = "回合结束时，你可以令X名角色的名字替换为易？剧，并获得〖大剧道〗。"..
  "（X为你本回合使用过牌的阶段数）",
  ["rfenghou__dajudao"] = "大剧道",
  [":rfenghou__dajudao"] = "〖大叫唤〗判定生效前，你可以打出一张黑色牌替换判定牌！",
  ["#rfenghou__dajiaohuan-use"] = "大叫唤：你可以使用这张牌",
  ["#rfenghou__lianxuju-choose"] = "连续剧：你可以令至多%arg名角色变为易X剧！",
  ["rfenghou1_yidaju"] = "易小剧",
  ["rfenghou2_yidaju"] = "易尖剧",
  ["rfenghou3_yidaju"] = "易太剧",
  ["rfenghou4_yidaju"] = "易犬剧",
  ["rfenghou5_yidaju"] = "易喜剧",
  ["rfenghou6_yidaju"] = "易悲剧",
  ["rfenghou7_yidaju"] = "易天剧",
  ["rfenghou8_yidaju"] = "易夭剧",
  ["rfenghou9_yidaju"] = "易京剧",
  ["rfenghou10_yidaju"] = "易黄梅戏",
  ["#rfenghou__dajudao-ask"] = "大剧道：你可以打出一张黑色牌替换 %dest 的〖大叫唤〗判定！",
}

local baixiaobei = General(extension, "rfenghou__baixiaobei", "fuyao", 3)
local siba = fk.CreateActiveSkill{
  name = "rfenghou__siba",
  anim_type = "control",
  prompt = "#rfenghou__siba",
  card_num = 0,
  target_num = 1,
  interaction = UI.ComboBox {choices = {
    "rfenghou__siba_xiyingxi",
    "rfenghou__siba_hushi",
    "rfenghou__siba_zhaoyu",
    "rfenghou__siba_lishu",
  }},
  can_use = function(self, player)
    return player:usedSkillTimes(self.name, Player.HistoryPhase) == 0
  end,
  card_filter = function (self, to_select, selected)
    if self.interaction.data == "rfenghou__siba_xiyingxi" then
      return false
    elseif self.interaction.data == "rfenghou__siba_hushi" then
      return false
    elseif self.interaction.data == "rfenghou__siba_zhaoyu" then
      local card = Fk:getCardById(to_select)
      return #selected == 0 and (card.trueName == "slash" or card.trueName == "jink")
    elseif self.interaction.data == "rfenghou__siba_lishu" then
      return #selected < 4
    end
  end,
  target_filter = function (self, to_select, selected)
    if self.interaction.data == "rfenghou__siba_xiyingxi" then
      local card = Fk:cloneCard("sincere_treat")
      card.skillName = self.name
      return card.skill:targetFilter(to_select, {}, {}, card, {bypass_distances = true})
    elseif self.interaction.data == "rfenghou__siba_hushi" then
      return #selected == 0 and Fk:currentRoom():getPlayerById(to_select):canMoveCardsInBoardTo(Self)
    elseif self.interaction.data == "rfenghou__siba_zhaoyu" then
      return false
    elseif self.interaction.data == "rfenghou__siba_lishu" then
      return false
    end
  end,
  feasible = function (self, selected, selected_cards)
    if self.interaction.data == "rfenghou__siba_xiyingxi" then
      local card = Fk:cloneCard("sincere_treat")
      card.skillName = self.name
      return #selected_cards == 0 and card.skill:feasible(selected, {}, Self, card)
    elseif self.interaction.data == "rfenghou__siba_hushi" then
      return #selected_cards == 0 and #selected == 1
    elseif self.interaction.data == "rfenghou__siba_zhaoyu" then
      return #selected_cards == 1 and #selected == 0
    elseif self.interaction.data == "rfenghou__siba_lishu" then
      return #selected_cards == 4 and #selected == 0
    end
  end,
  on_use = function(self, room, effect)
    local player = room:getPlayerById(effect.from)
    local orig_info = {"general", player.general}
    local str = "xiaobai__"..string.sub(self.interaction.data, 16)
    if Fk.generals[str] then
      if player.deputyGeneral ~= nil and player.deputyGeneral == "rfenghou__baixiaobei" then
        orig_info = {"deputy", player.deputyGeneral}
        player.deputyGeneral = str
        room:broadcastProperty(player, "deputyGeneral")
      else
        player.general = str
        room:broadcastProperty(player, "general")
      end
    end
    if self.interaction.data == "rfenghou__siba_xiyingxi" then
      local card = Fk:cloneCard("sincere_treat")
      card.skillName = self.name
      room:useCard{
        from = player.id,
        tos = table.map(effect.tos, function(id) return {id} end),
        card = card,
      }
    elseif self.interaction.data == "rfenghou__siba_hushi" then
      local target = room:getPlayerById(effect.tos[1])
      room:askForMoveCardInBoard(player, target, player, self.name, nil, target)
    elseif self.interaction.data == "rfenghou__siba_zhaoyu" then
      local name = Fk:getCardById(effect.cards[1]).trueName
      room:recastCard(effect.cards, player, self.name)
      if player.dead then return end
      if name == "slash" then
        room:addPlayerMark(player, "@@rfenghou__siba_jink", 1)
      elseif name == "jink" then
        room:addPlayerMark(player, "@@rfenghou__siba_slash", 1)
      end
    elseif self.interaction.data == "rfenghou__siba_lishu" then
      room:recastCard(effect.cards, player, self.name)
      local cards = table.filter(effect.cards, function (id)
        return Fk:getCardById(id).trueName == "slash" and table.contains(room.discard_pile, id)
      end)
      local used = {}
      while not player.dead and #cards > 0 do
        cards = table.filter(effect.cards, function (id)
          return Fk:getCardById(id).trueName == "slash" and table.contains(room.discard_pile, id) and
            not table.contains(used, id)
        end)
        if table.find(cards, function (id)
          local card = Fk:getCardById(id)
          return player:canUse(card, {bypass_times = false})
        end) then
          local use = U.askForUseRealCard(room, player, cards, "slash", self.name, "#rfenghou__siba-slash", {
            bypass_times = false,
            extraUse = false,
            expand_pile = cards,
          }, false, false)
          if use then
            table.insert(used, use.card.id)
          end
        else
          break
        end
      end
    end
    if Fk.generals[str] then
      if orig_info[1] == "deputy" then
        player.deputyGeneral = orig_info[2]
        room:broadcastProperty(player, "deputyGeneral")
      else
        player.general = orig_info[2]
        room:broadcastProperty(player, "general")
      end
    end
  end,
}
local siba_trigger = fk.CreateTriggerSkill{
  name = "#rfenghou__siba_trigger",
  mute = true,
  events = {fk.PreCardEffect},
  can_trigger = function(self, event, target, player, data)
    return player:getMark("@@rfenghou__siba_"..data.card.trueName) > 0
  end,
  on_cost = Util.TrueFunc,
  on_use = function(self, event, target, player, data)
    local room = player.room
    player:broadcastSkillInvoke("rfenghou__siba")
    room:notifySkillInvoked(player, "rfenghou__siba", "control")
    room:doIndicate(player.id, {target.id})
    room:setPlayerMark(player, "@@rfenghou__siba_"..data.card.trueName, 0)
    return true
  end,
}
local zhuanhuan = fk.CreateTriggerSkill{
  name = "rfenghou__zhuanhuan",
  anim_type = "control",
  events = {fk.EventPhaseStart},
  can_trigger = function(self, event, target, player, data)
    if player:hasSkill(self) then
      if target == player and player.phase == Player.Start then
        return not player:isNude()
      elseif target ~= player and target.phase == Player.Finish then
        return not target.dead and not target:isNude()
      end
    end
  end,
  on_cost = function(self, event, target, player, data)
    local suit = player:getTableMark("@rfenghou__zhuanhuan")[1]
    local pattern = ".|.|"..U.ConvertSuit(suit, "sym", "str")
    local card = player.room:askForDiscard(target, 1, 1, true, self.name, true, pattern,
      "#rfenghou__zhuanhuan-ask:"..player.id.."::"..suit, true)
    if #card > 0 then
      self.cost_data = {cards = card}
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    room:doIndicate(target.id, {player.id})
    local mark = player:getTableMark("@rfenghou__zhuanhuan")
    local suit = mark[1]
    table.remove(mark, 1)
    table.insert(mark, suit)
    room:setPlayerMark(player, "@rfenghou__zhuanhuan", mark)
    room:throwCard(self.cost_data.cards, self.name, target, target)
    if player.dead then return end
    room:askForUseActiveSkill(player, "rfenghou__siba", "#rfenghou__siba", true)
  end,

  on_acquire = function (self, player, is_start)
    player.room:setPlayerMark(player, "@rfenghou__zhuanhuan", {"log_heart", "log_spade", "log_club", "log_diamond"})
  end,
  on_lose = function (self, player, is_death)
    player.room:setPlayerMark(player, "@rfenghou__zhuanhuan", 0)
  end,
}
siba:addRelatedSkill(siba_trigger)
baixiaobei:addSkill(siba)
baixiaobei:addSkill(zhuanhuan)
Fk:loadTranslationTable{
  ["rfenghou__baixiaobei"] = "白小贝",
  ["#rfenghou__baixiaobei"] = "黑大壳",
  ["designer:rfenghou__baixiaobei"] = "胖即是胖",
  --["illustrator:rfenghou__baixiaobei"] = "",

  ["rfenghou__siba"] = "四八",
  [":rfenghou__siba"] = "出牌阶段限一次，你可以选择一项：1.视为使用一张无距离限制的【推心置腹】；2.将场上的一张牌移至你的场上；"..
  "3.重铸一张【杀】/【闪】并令被使用的下一张【闪】/【杀】无效；4.重铸四张牌并使用其中的【杀】（计入次数）。",
  ["rfenghou__zhuanhuan"] = "转换",
  [":rfenghou__zhuanhuan"] = "转换技，你的准备阶段或其他角色的结束阶段，当前回合角色可以弃置一张①<font color='red'>♥</font>②♠③♣"..
  "④<font color='red'>♦</font>牌并令你发动〖四八〗。",
  ["#rfenghou__siba"] = "四八：你可以执行一项",
  ["rfenghou__siba_xiyingxi"] = "视为使用一张无距离限制的【推心置腹】",
  ["rfenghou__siba_hushi"] = "将场上的一张牌移至你的场上",
  ["rfenghou__siba_zhaoyu"] = "重铸一张【杀】/【闪】并令被使用的下一张【闪】/【杀】无效",
  ["rfenghou__siba_lishu"] = "重铸四张牌并使用其中的【杀】",
  ["@@rfenghou__siba_slash"] = "四八 杀无效",
  ["@@rfenghou__siba_jink"] = "四八 闪无效",
  ["#rfenghou__siba-slash"] = "四八：请使用其中的【杀】",
  ["#rfenghou__siba_trigger"] = "四八",
  ["#rfenghou__zhuanhuan-ask"] = "转换：你可以弃置一张%arg牌令 %src 发动“四八”！",
  ["@rfenghou__zhuanhuan"] = "转换",
}

local yyuaN = General(extension, "rfenghou__yyuaN", "fuyao", 4)
local hujiao = fk.CreateTriggerSkill{
  name = "rfenghou__hujiao",
  anim_type = "control",
  events = {fk.PreCardUse, fk.EventPhaseStart},
  can_trigger = function(self, event, target, player, data)
    if target == player and player:hasSkill(self) then
      if event == fk.PreCardUse then
        return (player.phase == Player.Play or table.contains(data.card.skillNames, self.name)) and data.tos
      elseif event == fk.EventPhaseStart then
        return player.phase == Player.Finish and
          table.find(player:getTableMark("@$rfenghou__hujiao"), function (name)
            local card = Fk:cloneCard(name)
            card.skillName = self.name
            return card.type ~= Card.TypeEquip and card.sub_type ~= Card.SubtypeDelayedTrick and
              player:canUse(card, {bypass_distances = true, bypass_times = true})
          end)
      end
    end
  end,
  on_cost = function (self, event, target, player, data)
    if event == fk.PreCardUse then
      if table.contains(data.card.skillNames, self.name) then
        return true
      else
        return player.room:askForSkillInvoke(player, self.name, nil, "#rfenghou__hujiao-invoke:::"..data.card:toLogString())
      end
    elseif event == fk.EventPhaseStart then
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    if event == fk.PreCardUse then
      if player.phase == Player.Play then
        local mark = player:getTableMark("@$rfenghou__hujiao")
        table.insertIfNeed(mark, data.card.name)
        room:setPlayerMark(player, "@$rfenghou__hujiao", mark)
      end
      local targets = {}
      for _, orig_to in ipairs(data.tos) do
        for _, p in ipairs(room.alive_players) do
          if not player:isProhibited(p, data.card) and
          (data.card.sub_type == Card.SubtypeDelayedTrick or data.card.skill:modTargetFilter(p.id, {}, player.id, data.card, false)) then
            local ho_spair_check = true
            if #orig_to > 1 then
              --target_filter check, for collateral, diversion...
              local ho_spair_target = {p.id}
              for i = 2, #orig_to, 1 do
                local c_pid = orig_to[i]
                if not data.card.skill:modTargetFilter(c_pid, ho_spair_target, player.id, data.card, true) then
                  ho_spair_check = false
                  break
                end
                table.insert(ho_spair_target, c_pid)
              end
            end
            if ho_spair_check then
              table.insert(targets, p.id)
            end
          end
        end
      end
      if #targets > 0 then
        local random_target = table.random(targets)
        if #TargetGroup:getRealTargets(data.tos) == 1 then
          if #targets > 1 then
            for i = 1, 2, 1 do
              for _, p in ipairs(room:getAllPlayers()) do
                if table.contains(targets, p.id) then
                  room:setEmotion(p, "./image/anim/selectable")
                  room:notifyMoveFocus(p, self.name)
                  room:delay(300)
                end
              end
            end
            for _, p in ipairs(room:getAllPlayers()) do
              if table.contains(targets, p.id) then
                room:setEmotion(p, "./image/anim/selectable")
                room:delay(600)
                if p.id == random_target then
                  room:doIndicate(data.from, {random_target})
                  break
                end
              end
            end
          end
          data.tos[1][1] = random_target
        else
          local new_targets = table.random(targets, math.random(1, #TargetGroup:getRealTargets(data.tos)))
          for i = 1, #data.tos, 1 do
            if i <= #new_targets then
              data.tos[i][1] = new_targets[i]
            else
              data.tos[i] = nil
            end
          end
        end
      else
        data.tos = {}
      end
    elseif event == fk.EventPhaseStart then
      local all_names = table.simpleClone(player:getTableMark("@$rfenghou__hujiao"))
      local names, tmp = {}, {}
      for _, name in ipairs(all_names) do
        if not tmp[name] then
          table.insert(names, name)
          tmp[name] = true
        end
      end
      for _, name in ipairs(names) do
        if player.dead then return end
        local card = Fk:cloneCard(name)
        card.skillName = self.name
        if card.type ~= Card.TypeEquip and card.sub_type ~= Card.SubtypeDelayedTrick and
          player:canUse(card, {bypass_distances = true, bypass_times = true}) then
          if card.multiple_targets and card.skill.min_target_num == 0 then
            room:useCard{
              from = player.id,
              card = card,
              extraUse = true,
            }
          else
            room:useCard{
              from = player.id,
              tos = {{player:getNextAlive().id}},
              card = card,
              extraUse = true,
            }
          end
        end
      end
    end
  end,
}
yyuaN:addSkill(hujiao)
Fk:loadTranslationTable{
  ["rfenghou__yyuaN"] = "yyuaN低调的温柔胖宝宝",
  ["#rfenghou__yyuaN"] = "娇蛮小公主",
  ["designer:rfenghou__yyuaN"] = "zzcclll朱苦力",
  --["illustrator:rfenghou__yyuaN"] = "",

  ["rfenghou__hujiao"] = "胡搅",
  [":rfenghou__hujiao"] = "出牌阶段，你使用牌时，可令之随机指定目标。结束阶段，你依次视为使用本局你使用过的“胡搅”牌每牌名各一张，且均须触发“胡搅”。",
  ["#rfenghou__hujiao-invoke"] = "胡搅：是否令%arg随机指定目标？",
  ["@$rfenghou__hujiao"] = "胡搅",
}

local miaomiao = General(extension, "rfenghou__miaomiao", "fuyao", 4)
local juer = fk.CreateTriggerSkill{
  name = "rfenghou__juer",
  anim_type = "defensive",
  events = { fk.TargetConfirming, fk.BeforeCardsMove },
  frequency = Skill.Compulsory,
  can_trigger = function(self, event, target, player, data)
    if not player:hasSkill(self) then return end
    if event == fk.TargetConfirming then
      return (target == player or data.from == player.id) and
        (data.card.number == 2 or Fk:translate(data.card.trueName, "zh_CN"):len() == 2)
    elseif event == fk.BeforeCardsMove then
      local id = 0
      local source = player
      local card
      for _, move in ipairs(data) do
        if move.to == player.id and move.toArea == Card.PlayerJudge then
          for _, info in ipairs(move.moveInfo) do
            id = info.cardId
            if info.fromArea == Card.PlayerJudge then
              source = player.room:getPlayerById(move.from) or player
            else
              source = player
            end
            card = source:getVirualEquip(id)
            if not card then card = Fk:getCardById(id) end
            if card.sub_type == Card.SubtypeDelayedTrick and
              (card.number == 2 or Fk:translate(card.trueName, "zh_CN"):len() == 2) then
              return true
            end
          end
        end
      end
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    if event == fk.TargetConfirming then
      AimGroup:cancelTarget(data, target.id)
      return true
    elseif event == fk.BeforeCardsMove then
      local source = player
      local mirror_moves = {}
      local ids = {}
      for _, move in ipairs(data) do
        if move.to == player.id and move.toArea == Card.PlayerJudge then
          local move_info = {}
          local mirror_info = {}
          for _, info in ipairs(move.moveInfo) do
            local id = info.cardId
            if info.fromArea == Card.PlayerJudge then
              source = room:getPlayerById(move.from) or player
            else
              source = player
            end
            local card = source:getVirualEquip(id)
            if not card then card = Fk:getCardById(id) end
            if card.sub_type == Card.SubtypeDelayedTrick and
              (card.number == 2 or Fk:translate(card.trueName, "zh_CN"):len() == 2) then
              table.insert(mirror_info, info)
              table.insert(ids, id)
            else
              table.insert(move_info, info)
            end
          end
          if #mirror_info > 0 then
            move.moveInfo = move_info
            local mirror_move = table.clone(move)
            mirror_move.to = nil
            mirror_move.toArea = Card.DiscardPile
            mirror_move.moveInfo = mirror_info
            table.insert(mirror_moves, mirror_move)
          end
        end
      end
      table.insertTable(data, mirror_moves)
    end
  end
}
local aisui = fk.CreateTriggerSkill{
  name = "rfenghou__aisui",
  anim_type = "control",
  frequency = Skill.Compulsory,
  events = {fk.EventPhaseStart, fk.EventPhaseProceeding},
  can_trigger = function(self, event, target, player, data)
    if target == player and player:hasSkill(self) then
      if event == fk.EventPhaseStart then
        return player.phase == Player.Play
      elseif event == fk.EventPhaseProceeding then
        if player.phase == Player.Judge then
          return not player:isAllNude()
        elseif player.phase == Player.Draw then
          return #player:getCardIds("e") > 0 or
            table.find(player.room:getOtherPlayers(player), function (p)
              return not p:isNude()
            end)
        elseif player.phase == Player.Discard then
          return table.find(player.room.alive_players, function (p)
            return table.find(p:getCardIds("he"), function (id)
              return not player:prohibitDiscard(id)
            end)
          end)
        end
      end
    end
  end,
  on_use = function (self, event, target, player, data)
    local room = player.room
    if event == fk.EventPhaseStart then
      local skills = {}
      for _, general in ipairs(Fk:getAllGenerals()) do
        for _, skill in ipairs(general.skills) do
          if not player:hasSkill(skill, true) and string.find(Fk:translate(":"..skill.name, "zh_CN"), "出牌阶段限一次") then
            table.insertIfNeed(skills, skill.name)
          end
        end
      end
      if #skills > 0 then
        local skill = table.random(skills)
        room:addTableMark(player, self.name, skill)
        room:handleAddLoseSkills(player, skill, nil, true, false)
      end
    elseif event == fk.EventPhaseProceeding then
      if player.phase == Player.Judge then
        room:recastCard(player:getCardIds("hej"), player, self.name)
        if not player.dead then
          local judge = {
            who = player,
            reason = "lightning",
            pattern = ".|2~9|spade",
          }
          room:judge(judge)
          if not player.dead and
            judge.card.suit == Card.Spade and judge.card.number > 1 and judge.card.number < 10 then
            room:damage{
              to = player,
              damage = 3,
              damageType = fk.ThunderDamage,
              skillName = self.name,
            }
          end
        end
        player._phase_end = true
      elseif player.phase == Player.Draw then
        local targets = {}
        if #player:getCardIds("e") > 0 then
          table.insert(targets, player.id)
        end
        for _, p in ipairs(room:getOtherPlayers(player)) do
          if not p:isNude() then
            table.insert(targets, p.id)
          end
        end
        targets = table.random(targets, math.random(1, #targets))
        local moves = {}
        for _, id in ipairs(targets) do
          local ids
          if id == player.id then
            ids = table.random(player:getCardIds("e"), 1)
          else
            ids = table.random(room:getPlayerById(id):getCardIds("he"), 1)
          end
          table.insert(moves, {
            from = id,
            to = player.id,
            ids = ids,
            toArea = Card.PlayerHand,
            moveReason = fk.ReasonPrey,
            skillName = self.name,
            proposer = player.id,
            moveVisible = false,
          })
        end
        if #moves > 0 then
          room:moveCards(table.unpack(moves))
          player._phase_end = true
        end
      elseif player.phase == Player.Discard then
        local targets = table.filter(room.alive_players, function (p)
          return table.find(p:getCardIds("he"), function (id)
            return not player:prohibitDiscard(id)
          end) ~= nil
        end)
        targets = table.random(targets, math.random(1, #targets))
        local moves = {}
        for _, p in ipairs(targets) do
          local ids
          if p == player.id then
            ids = table.random(table.filter(player:getCardIds("he"), function (id)
              return not player:prohibitDiscard(id)
            end), 1)
          else
            ids = table.random(p:getCardIds("he"), 1)
          end
          table.insert(moves, {
            from = p.id,
            ids = ids,
            toArea = Card.DiscardPile,
            moveReason = fk.ReasonDiscard,
            skillName = self.name,
            proposer = player.id,
            moveVisible = true,
          })
        end
        if #moves > 0 then
          room:moveCards(table.unpack(moves))
          player._phase_end = true
        end
      end
    end
  end,

  refresh_events = {fk.AfterSkillEffect},
  can_refresh = function (self, event, target, player, data)
    return target == player and table.contains(player:getTableMark(self.name), data.name)
  end,
  on_refresh = function (self, event, target, player, data)
    local room = player.room
    room:removeTableMark(player, self.name, data.name)
    room:handleAddLoseSkills(player, "-"..data.name, nil, true, false)
  end,
}
miaomiao:addSkill(juer)
miaomiao:addSkill(aisui)
Fk:loadTranslationTable{
  ["rfenghou__miaomiao"] = "独孤妙妙",
  ["#rfenghou__miaomiao"] = "云月有归处",
  ["designer:rfenghou__miaomiao"] = "扬林",
  --["illustrator:rfenghou__miaomiao"] = "",

  ["rfenghou__juer"] = "拒贰",
  [":rfenghou__juer"] = "锁定技，你使用或被使用点数或牌名字数为2的牌时，取消之。",
  ["rfenghou__aisui"] = "爱随",
  [":rfenghou__aisui"] = "锁定技，判定阶段，你重铸区域内所有牌，执行一次【闪电】判定；出牌阶段，你随机获得一项“出牌阶段限一次”的技能，"..
  "且发动后失去之；摸牌/弃牌阶段，你改为随机获得/弃置任意名角色各一张牌。",
}

local pangpang = General(extension, "rfenghou__pangpang", "fuyao", 3)
local queyi = fk.CreateViewAsSkill{
  name = "rfenghou__queyi",
  pattern = ".",
  prompt = function (self, selected_cards, selected)
    local arg1, arg2 = "", ""
      if Fk:cloneCard(self.interaction.data).type == Card.TypeBasic then
        local suits = {1, 2, 3, 4}
        for _, id in ipairs(Fk:currentRoom():getBanner("@$CenterArea")) do
          table.removeOne(suits, Fk:getCardById(id).suit)
        end
        arg1 = U.ConvertSuit(suits[1], "int", "sym")
        arg2 = "basic"
      else
        local types = {1, 2, 3}
        for _, id in ipairs(Fk:currentRoom():getBanner("@$CenterArea")) do
          table.removeOne(types, Fk:getCardById(id).type)
        end
        local mapper = {"basic", "trick", "equip"}
        arg1 = mapper[types[1]]
        arg2 = "trick"
      end
    return "#rfenghou__queyi:::"..arg1..":"..arg2
  end,
  interaction = function(self)
    local all_names = {}
    local suits, types = {}, {}
    for _, id in ipairs(Fk:currentRoom():getBanner("@$CenterArea")) do
      table.insertIfNeed(suits, Fk:getCardById(id).suit)
      table.insertIfNeed(types, Fk:getCardById(id).type)
    end
    table.removeOne(suits, Card.NoSuit)
    if #suits == 3 and #types == 2 then
      all_names = U.getAllCardNames("bt")
    elseif #suits == 3 then
      all_names = U.getAllCardNames("b")
    elseif #types == 2 then
      all_names = U.getAllCardNames("t")
    end
    return U.CardNameBox {
      choices = U.getViewAsCardNames(Self, self.name, all_names),
      all_choices = all_names,
    }
  end,
  card_filter = function(self, to_select, selected)
    if #selected == 0 and Fk.all_card_types[self.interaction.data] ~= nil then
      if Fk:cloneCard(self.interaction.data).type == Card.TypeBasic then
        local suits = {1, 2, 3, 4}
        for _, id in ipairs(Fk:currentRoom():getBanner("@$CenterArea")) do
          table.removeOne(suits, Fk:getCardById(id).suit)
        end
        return Fk:getCardById(to_select).suit == suits[1]
      else
        local types = {1, 2, 3}
        for _, id in ipairs(Fk:currentRoom():getBanner("@$CenterArea")) do
          table.removeOne(types, Fk:getCardById(id).type)
        end
        return Fk:getCardById(to_select).type == types[1]
      end
    end
  end,
  view_as = function(self, cards)
    if #cards ~= 1 or Fk.all_card_types[self.interaction.data] == nil then return end
    local card = Fk:cloneCard(self.interaction.data)
    card:addSubcard(cards[1])
    card.skillName = self.name
    return card
  end,
  enabled_at_play = function (self, player)
    local suits, types = {}, {}
    for _, id in ipairs(Fk:currentRoom():getBanner("@$CenterArea")) do
      table.insertIfNeed(suits, Fk:getCardById(id).suit)
      table.insertIfNeed(types, Fk:getCardById(id).type)
    end
    table.removeOne(suits, Card.NoSuit)
    return #suits == 3 or #types == 2
  end,
  enabled_at_response = function (self, player, response)
    if response or player:isNude() then return end
    local suits, types = {}, {}
    for _, id in ipairs(Fk:currentRoom():getBanner("@$CenterArea")) do
      table.insertIfNeed(suits, Fk:getCardById(id).suit)
      table.insertIfNeed(types, Fk:getCardById(id).type)
    end
    table.removeOne(suits, Card.NoSuit)
    local all_names = {}
    if #suits == 3 and #types == 2 then
      all_names = U.getAllCardNames("bt")
    elseif #suits == 3 then
      all_names = U.getAllCardNames("b")
    elseif #types == 2 then
      all_names = U.getAllCardNames("t")
    end
    for _, name in ipairs(all_names) do
      local card = Fk:cloneCard(name)
      card.skillName = self.name
      if #suits == 3 then
        card.suit = suits[1]
      end
      if (Fk.currentResponsePattern == nil and player:canUse(card)) or
        (Fk.currentResponsePattern and Exppattern:Parse(Fk.currentResponsePattern):match(card)) then
        return true
      end
    end
  end,
}
local atgroup = fk.CreateActiveSkill{
  name = "rfenghou__atgroup",
  anim_type = "control",
  card_num = 0,
  target_num = 0,
  prompt = "#rfenghou__atgroup",
  can_use = function(self, player)
    if player:usedSkillTimes(self.name, Player.HistoryPhase) == 0 and
      table.find(Fk:currentRoom().alive_players, function (p)
        if table.find(p:getCardIds("he"), function (id)
          return not Self:prohibitDiscard(id)
        end) then
          return true
        end
      end) then
      return true
    end
  end,
  card_filter = Util.FalseFunc,
  on_use = function(self, room, effect)
    local player = room:getPlayerById(effect.from)
    local targets, n = {}, 0
    for _, p in ipairs(room:getAlivePlayers()) do
      if player.dead then return end
      local card
      if p == player then
        card = room:askForDiscard(player, 1, 1, true, self.name, false, nil, "#rfenghou__atgroup-discard::"..player.id)
        if #card > 0 then
          n = n + 1
          if Fk:getCardById(card[1]).type == Card.TypeEquip then
            table.insert(targets, player)
          end
        end
      elseif not p:isNude() then
        card = room:askForCardChosen(player, p, "he", self.name, "#rfenghou__atgroup-discard::"..p.id)
        n = n + 1
        if card and Fk:getCardById(card).type == Card.TypeEquip then
          table.insert(targets, p)
        end
        room:throwCard(card, self.name, p, player)
      end
    end
    n = math.min(#room:getBanner("@$CenterArea"), n)
    if player.dead or n == 0 then return end
    local result = room:askForArrangeCards(player, self.name,
    {
      {}, room:getBanner("@$CenterArea"),
      "Top", "$CenterArea",
    }, "#rfenghou__atgroup-put:::"..n, true, #room:getBanner("@$CenterArea"), {n, 999})
    if #result[1] > 0 then
      result[1] = table.reverse(result[1])
      room:moveCards({
        ids = result[1],
        fromArea = Card.DiscardPile,
        toArea = Card.DrawPile,
        moveReason = fk.ReasonPut,
        skillName = self.name,
        moveVisible = true,
        drawPilePosition = 1,
      })
    end
    if player.dead then return end
    local card = Fk:cloneCard("amazing_grace")
    card.skillName = self.name
    if not player:canUse(card) then return end
    if #targets > 0 and room:askForSkillInvoke(player, self.name, nil, "#rfenghou__atgroup-cancel") then
      local tos = {}
      for _, p in ipairs(room:getAlivePlayers()) do
        if not table.contains(targets, p) and player:canUseTo(card, p) then
          table.insert(tos, {p.id})
        end
      end
      if #tos > 0 then
        room:useCard{
          from = player.id,
          tos = tos,
          card = card,
        }
      end
    else
      room:useCard{
        from = player.id,
        card = card,
      }
    end
  end,
}
queyi.CenterArea = true
atgroup.CenterArea = true
pangpang:addSkill(queyi)
pangpang:addSkill(atgroup)
Fk:loadTranslationTable{
  ["rfenghou__pangpang"] = "胖即是胖",
  ["#rfenghou__pangpang"] = "@全体成员",
  ["designer:rfenghou__pangpang"] = "屑",
  --["illustrator:rfenghou__pangpang"] = "",

  ["rfenghou__queyi"] = "缺1",
  [":rfenghou__queyi"] = "若中央区仅缺少一种花色/类型的牌，你可以将一张此花色/类型的牌当任意基本/普通锦囊牌使用。",
  ["rfenghou__atgroup"] = "@全体成员",
  [":rfenghou__atgroup"] = "出牌阶段限一次，你可以弃置所有角色各一张牌，然后将中央区至多等量张牌置于牌堆顶，视为使用一张【五谷丰登】，"..
  "且可令弃置装备牌的角色不成为目标。",
  ["#rfenghou__queyi"] = "缺1：你可以将一张%arg当任意%arg2使用",
  ["#rfenghou__atgroup"] = "@全体成员：弃置所有角色各一张牌，然后将中央区的牌置于牌堆顶，视为使用【五谷丰登】",
  ["#rfenghou__atgroup-discard"] = "@全体成员：弃置 %dest 一张牌",
  ["#rfenghou__atgroup-put"] = "@全体成员：将中央区至多%arg张牌置于牌堆顶",
  ["#rfenghou__atgroup-cancel"] = "@全体成员：是否令弃置装备牌的角色不成为目标？",
}

local yanglin = General(extension, "rfenghou__yanglin", "fuyao", 4)
local shanebao = fk.CreateTriggerSkill{
  name = "rfenghou__shanebao",
  mute = true,
  frequency = Skill.Compulsory,
  events = {--fk.AfterCardsMove, 
  fk.AfterCardTargetDeclared},
  can_trigger = function(self, event, target, player, data)
    if player:hasSkill(self) then
      local turn_event = player.room.logic:getCurrentEvent():findParent(GameEvent.Turn)
      if turn_event == nil then return end
      --[[if event == fk.AfterCardsMove then
        if #player.room.logic:getEventsOfScope(GameEvent.MoveCards, 1, function(e)
          if e.id ~= player.room.logic:getCurrentEvent().id then
            for _, move in ipairs(e.data) do
              if move.from then
                for _, info in ipairs(move.moveInfo) do
                  if info.fromArea == Card.PlayerHand or info.fromArea == Card.PlayerEquip then
                    return true
                  end
                end
              end
            end
          end
        end, Player.HistoryTurn) == 0 then return end
        for _, move in ipairs(data) do
          if move.to == player.id and move.moveReason == fk.ReasonDraw and move.skillName ~= self.name then
            return true
          end
          if move.from == player.id and move.moveReason == fk.ReasonDiscard and move.skillName ~= self.name and
            move.proposer == player.id and not player:isNude() then
            for _, info in ipairs(move.moveInfo) do
              if info.fromArea == Card.PlayerHand or info.fromArea == Card.PlayerEquip then
                return true
              end
            end
          end
        end
      else]]--
      if event == fk.AfterCardTargetDeclared and data.card.trueName == "slash" then
        if #player.room.logic:getEventsOfScope(GameEvent.Recover, 1, Util.TrueFunc, Player.HistoryTurn) == 0 then return end
        if #player.room:getUseExtraTargets(data) == 0 then return end
        return target == player or table.contains(TargetGroup:getRealTargets(data.tos), player.id)
      end
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    player:broadcastSkillInvoke(self.name)
    --[[if event == fk.AfterCardsMove then
      local targets = {}
      room.logic:getEventsOfScope(GameEvent.MoveCards, 1, function(e)
        for _, move in ipairs(e.data) do
          if move.from then
            for _, info in ipairs(move.moveInfo) do
              if info.fromArea == Card.PlayerHand or info.fromArea == Card.PlayerEquip then
                table.insertIfNeed(targets, move.from)
              end
            end
          end
        end
      end, Player.HistoryTurn)
      local n = #targets
      local yes1, yes2 = false, false
      for _, move in ipairs(data) do
        if move.to == player.id and move.moveReason == fk.ReasonDraw and move.skillName ~= self.name then
          yes1 = true
        end
        if not player:hasSkill(self) then return end
        if move.from == player.id and move.moveReason == fk.ReasonDiscard and move.skillName ~= self.name and
          move.proposer == player.id then
          for _, info in ipairs(move.moveInfo) do
            if info.fromArea == Card.PlayerHand or info.fromArea == Card.PlayerEquip then
              yes2 = true
              break
            end
          end
        end
      end
      if yes1 then
        room:notifySkillInvoked(player, self.name, "drawcard")
        player:drawCards(n, self.name)
      end
      if not player:hasSkill(self) then return end
      if yes2 and not player:isNude() then
        room:notifySkillInvoked(player, self.name, "negative")
        room:askForDiscard(player, n, n, true, self.name, false)
      end
    else]]--
    if event == fk.AfterCardTargetDeclared then
      local targets = {}
      room.logic:getEventsOfScope(GameEvent.Recover, 1, function(e)
        local recover = e.data[1]
        table.insertIfNeed(targets, recover.who.id)
      end, Player.HistoryTurn)
      local n = #targets
      targets = room:getUseExtraTargets(data)
      local tos = room:askForChoosePlayers(target, targets, 1, n,
        "#rfenghou__shanebao-choose:::"..data.card:toLogString()..":"..n, self.name, true)
      if #tos > 0 then
        for _, id in ipairs(tos) do
          table.insert(data.tos, {id})
        end
      end
    end
  end,
}
local beihuanqu = fk.CreateTriggerSkill{
  name = "rfenghou__beihuanqu",
  anim_type = "control",
  frequency = Skill.Compulsory,
  events = {fk.EventPhaseStart},
  can_trigger = function (self, event, target, player, data)
    if target == player and player:hasSkill(self) then
      if player.phase == Player.Start then
        return true
      elseif player.phase == Player.Finish then
        return #player:getTableMark("rfenghou__beihuanqu-turn") > 0 or
          #player.room.logic:getEventsOfScope(GameEvent.Dying, 1, Util.TrueFunc, Player.HistoryTurn) > 0
      end
    end
  end,
  on_use = function (self, event, target, player, data)
    local room = player.room
    if player.phase == Player.Start then
      room:doIndicate(player.id, table.map(room.alive_players, Util.IdMapper))
      for _, p in ipairs(room:getAlivePlayers()) do
        if not p.dead then
          local success, dat = room:askForUseActiveSkill(p, "rfenghou__beihuanqu_active",
            "#rfenghou__beihuanqu-choice", true, nil, false)
          if success and dat then
            if #dat.cards > 0 then
              room:throwCard(dat.cards, self.name, p, p)
            elseif #dat.targets > 0 then
              local to = room:getPlayerById(dat.targets[1])
              room:recover{
                who = to,
                num = 1,
                recoverBy = p,
                skillName = self.name,
              }
              if p:isWounded() and not p.dead then
                room:recover{
                  who = p,
                  num = 1,
                  recoverBy = p,
                  skillName = self.name,
                }
              end
            end
          else
            room:loseHp(p, 1, self.name)
          end
        end
      end
    elseif player.phase == Player.Finish then
      local targets = table.simpleClone(player:getTableMark("rfenghou__beihuanqu-turn"))
      room.logic:getEventsOfScope(GameEvent.Dying, 1, function(e)
        table.insertIfNeed(targets, e.data[1].who)
      end, Player.HistoryTurn)
      player:drawCards(#targets, self.name)
    end
  end,

  refresh_events = {fk.HpRecover},
  can_refresh = function (self, event, target, player, data)
    if not target:isWounded() then
      local turn_event = player.room.logic:getCurrentEvent():findParent(GameEvent.Turn)
      return turn_event and turn_event.data[1] == player
    end
  end,
  on_refresh = function (self, event, target, player, data)
    local mark = player:getTableMark("rfenghou__beihuanqu-turn")
    table.insertIfNeed(mark, target.id)
    player.room:setPlayerMark(player, "rfenghou__beihuanqu-turn", mark)
  end,
}
local beihuanqu_active = fk.CreateActiveSkill{
  name = "rfenghou__beihuanqu_active",
  min_card_num = 0,
  max_card_num = 2,
  min_target_num = 0,
  max_target_num = 1,
  card_filter = function (self, to_select, selected)
    return #selected < 2 and table.contains(Self:getCardIds("h"), to_select) and not Self:prohibitDiscard(to_select)
  end,
  target_filter = function(self, to_select, selected, selected_cards)
    return #selected_cards == 0 and #selected == 0 and to_select ~= Self.id and
      Fk:currentRoom():getPlayerById(to_select):isWounded()
  end,
  feasible = function (self, selected, selected_cards)
    return (#selected_cards == 2 and #selected == 0) or (#selected_cards == 0 and #selected == 1)
  end,
}
Fk:addSkill(beihuanqu_active)
yanglin:addSkill(shanebao)
yanglin:addSkill(beihuanqu)
Fk:loadTranslationTable{
  ["rfenghou__yanglin"] = "扬林",
  ["#rfenghou__yanglin"] = "星の缘",
  ["designer:rfenghou__yanglin"] = "志文",
  --["illustrator:rfenghou__yanglin"] = "",

  ["rfenghou__shanebao"] = "善恶报",
  [":rfenghou__shanebao"] = "锁定技，你使用或被使用【杀】时，使用【杀】的角色能指定至多X名角色为额外目标（X为此回合回复体力的角色数）。",
  ["rfenghou__beihuanqu"] = "悲欢曲",
  [":rfenghou__beihuanqu"] = "锁定技，准备阶段，所有角色依次选择：失去1点体力；弃置两张手牌；和另一名已受伤的角色各回复1点体力。"..
  "结束阶段，你摸Y张牌（Y为此回合进入濒死和回满体力的角色数之和）。",
  ["#rfenghou__shanebao-choose"] = "善恶报：你可以为此%arg额外指定至多%arg2个目标",
  ["rfenghou__beihuanqu_active"] = "悲欢曲",
  ["#rfenghou__beihuanqu-choice"] = "点“取消”失去1点体力；<br>选择两张手牌弃置；<br>"..
  "选择另一名已受伤角色，你与其各回复1点体力",
}

local toufa = General(extension, "rfenghou__toufa", "fuyao", 4)
local canxi = fk.CreateTriggerSkill{
  name = "rfenghou__canxi",
  frequency = Skill.Compulsory,
  events = {fk.DamageCaused, fk.HpRecover, fk.TargetConfirmed, fk.GameStart, fk.RoundStart},
  mute = true,
  can_trigger = function (self, event, target, player, data)
    if not player:hasSkill(self) then return false end
    if event == fk.DamageCaused then
      return target and player:getMark("@rfenghou__canxi1-round") == target.kingdom and
        not table.contains(player:getTableMark("rfenghou__canxi1-turn"), target.id)
    elseif event == fk.HpRecover then
      return player:getMark("@rfenghou__canxi2-round") == target.kingdom and
      not target.dead and target ~= player and not table.contains(player:getTableMark("rfenghou__canxi21-turn"), target.id)
    elseif event == fk.TargetConfirmed then
      if player == target and data.from ~= player.id then
        local p = player.room:getPlayerById(data.from)
        return player:getMark("@rfenghou__canxi2-round") == p.kingdom and
          not table.contains(player:getTableMark("rfenghou__canxi22-turn"), p.id)
      end
    elseif event == fk.RoundStart then
      return #player:getTableMark("@rfenghou__canxi_exist_kingdoms") > 0
    elseif event == fk.GameStart then
      return true
    end
  end,
  on_use = function (self, event, target, player, data)
    local room = player.room
    player:broadcastSkillInvoke(self.name)
    if event == fk.DamageCaused then
      room:notifySkillInvoked(player, self.name, "offensive")
      local mark = player:getTableMark("rfenghou__canxi1-turn")
      table.insert(mark, target.id)
      room:setPlayerMark(player, "rfenghou__canxi1-turn", mark)
      data.damage = data.damage + 1
    elseif event == fk.HpRecover then
      room:notifySkillInvoked(player, self.name, "control")
      local mark = player:getTableMark("rfenghou__canxi21-turn")
      table.insert(mark, target.id)
      room:setPlayerMark(player, "rfenghou__canxi21-turn", mark)
      room:loseHp(target, 1, self.name)
    elseif event == fk.TargetConfirmed then
      room:notifySkillInvoked(player, self.name, "defensive")
      local mark = player:getTableMark("rfenghou__canxi22-turn")
      table.insert(mark, data.from)
      room:setPlayerMark(player, "rfenghou__canxi22-turn", mark)
      table.insertIfNeed(data.nullifiedTargets, player.id)
    elseif event == fk.RoundStart then
      room:notifySkillInvoked(player, self.name, "special")
      local choice1 = room:askForChoice(player, player:getMark("@rfenghou__canxi_exist_kingdoms"), self.name, "#rfenghou__canxi-choice1")
      local choice2 = room:askForChoice(player, {"rfenghou__canxi1", "rfenghou__canxi2"}, self.name,
        "#rfenghou__canxi-choice2:::"..choice1, true)
      room:setPlayerMark(player, "@"..choice2.."-round", choice1)
    elseif event == fk.GameStart then
      room:notifySkillInvoked(player, self.name, "special")
      local kingdoms = {}
      for _, p in ipairs(room.alive_players) do
        table.insertIfNeed(kingdoms, p.kingdom)
      end
      room:setPlayerMark(player, "@rfenghou__canxi_exist_kingdoms", kingdoms)
      if #kingdoms < #Fk:getKingdomMap("god") then  --youmu智慧最有用的一集
        room:changeMaxHp(player, #Fk:getKingdomMap("god") - #kingdoms)
      end
    end
  end,

  on_lose = function (self, player, is_death)
    local room = player.room
    room:setPlayerMark(player, "@rfenghou__canxi_exist_kingdoms", 0)
    room:setPlayerMark(player, "@rfenghou__canxi1-round", 0)
    room:setPlayerMark(player, "@rfenghou__canxi2-round", 0)
  end,
}
local canxi_distance = fk.CreateDistanceSkill{
  name = "#rfenghou__canxi_distance",
  frequency = Skill.Compulsory,
  correct_func = function(self, from, to)
    return -#table.filter(Fk:currentRoom().alive_players, function (p)
      return p:hasSkill(canxi) and p:getMark("@rfenghou__canxi1-round") == from.kingdom
    end)
  end,
}
local pizhi = fk.CreateTriggerSkill{
  name = "rfenghou__pizhi",
  anim_type = "drawcard",
  frequency = Skill.Compulsory,
  events = {fk.EventPhaseEnd, fk.Death},
  can_trigger = function (self, event, target, player, data)
    if player:hasSkill(self) then
      if event == fk.EventPhaseEnd then
        return target == player and player.phase == Player.Finish and player:getMark("rfenghou__canxi_removed_kingdoms") > 0
      elseif event == fk.Death then
        return player:getMark("@rfenghou__canxi1-round") == target.kingdom or
          player:getMark("@rfenghou__canxi2-round") == target.kingdom or
          (not table.find(player.room.alive_players, function(p)
            return p.kingdom == target.kingdom
          end) and table.contains(player:getTableMark("@rfenghou__canxi_exist_kingdoms"), target.kingdom))
      end
    end
  end,
  on_use = function (self, event, target, player, data)
    local room = player.room
    if event == fk.Death then
      if player:getMark("@rfenghou__canxi1-round") == target.kingdom then
        room:setPlayerMark(player, "@rfenghou__canxi1-round", 0)
      end
      if player:getMark("@rfenghou__canxi2-round") == target.kingdom then
        room:setPlayerMark(player, "@rfenghou__canxi2-round", 0)
      end
      local mark = player:getMark("@rfenghou__canxi_exist_kingdoms")
      if table.removeOne(mark, target.kingdom) then
        room:setPlayerMark(player, "@rfenghou__canxi_exist_kingdoms", #mark > 0 and mark or 0)
        room:addPlayerMark(player, "rfenghou__canxi_removed_kingdoms")
      end
      player:drawCards(player:getMark("rfenghou__canxi_removed_kingdoms"), self.name)
      if not player.dead and player:isWounded() then
        room:recover({
          who = player,
          num = 1,
          recoverBy = player,
          skillName = self.name
        })
      end
    else
      player:drawCards(player:getMark("rfenghou__canxi_removed_kingdoms"), self.name)
    end
  end,
}
local zhonggu = fk.CreateTriggerSkill{
  name = "rfenghou__zhonggu$",
  mute = true,
  frequency = Skill.Compulsory,
  events = {fk.DrawNCards},
  on_use = function(self, event, target, player, data)
    local room = player.room
    player:broadcastSkillInvoke(self.name)
    local n = #table.filter(room.alive_players, function(p)
      return Fk.generals[p.general].package.extensionName == "hanqing"
    end)
    if room:getTag("RoundCount") >= n then
      room:notifySkillInvoked(player, self.name, "drawcard")
      data.n = data.n + 2
    else
      room:notifySkillInvoked(player, self.name, "negative")
      data.n = data.n - 1
    end
  end,
}
canxi:addRelatedSkill(canxi_distance)
toufa:addSkill(canxi)
toufa:addSkill(pizhi)
toufa:addSkill(zhonggu)
Fk:loadTranslationTable{
  ["rfenghou__toufa"] = "头发好借好还",
  ["#rfenghou__toufa"] = "头发好借好还",
  ["designer:rfenghou__toufa"] = "头发好借好还",
  --["illustrator:rfenghou__toufa"] = "",

  ["rfenghou__canxi"] = "残玺",
  [":rfenghou__canxi"] = "锁定技，游戏开始时，你获得场上各势力的“玺角”标记（每少一个“玺角”便加1点体力上限）。每轮开始时，"..
  "你选择一个“玺角”并选择一个效果生效直到下轮开始<br>「妄生」：该势力角色每回合首次造成伤害+1，计算与其他角色距离-1；<br>"..
  "「向死」：该势力其他角色每回合首次回复体力后失去1点体力，每回合对你使用的第一张牌无效。",
  ["rfenghou__pizhi"] = "圮秩",
  [":rfenghou__pizhi"] = "锁定技，结束阶段，你摸X张牌；有角色死亡时，若其势力与当前生效的“玺角”势力相同或是该势力最后一名角色，你失去此“玺角”，"..
  "然后摸X张牌并回复1点体力（X为你已失去的“玺角”数）。",
  ["rfenghou__zhonggu"] = "冢骨",
  [":rfenghou__zhonggu"] = "主公技，锁定技，游戏轮数大于等于汗青角色数时，你摸牌阶段摸牌数+2，反之-1。",

  ["@rfenghou__canxi_exist_kingdoms"] = "",
  ["#rfenghou__canxi-choice1"] = "残玺：选择本轮生效的“玺角”势力",
  ["#rfenghou__canxi-choice2"] = "残玺：选择本轮对 %arg 势力角色生效的效果",
  ["rfenghou__canxi1"] = "「妄生」",
  [":rfenghou__canxi1"] = "每回合首次造成伤害+1，计算与其他角色距离-1",
  ["@rfenghou__canxi1-round"] = "「妄生」",
  ["rfenghou__canxi2"] = "「向死」",
  [":rfenghou__canxi2"] = "每回合首次回复体力后失去1点体力，每回合对你使用的第一张牌无效",
  ["@rfenghou__canxi2-round"] = "「向死」",
}

Fk:loadTranslationTable{
  ["rfenghou__xie"] = "屑",
  ["#rfenghou__xie"] = "",
  ["designer:rfenghou__xie"] = "花生",
  --["illustrator:rfenghou__xie"] = "",

  ["rfenghou__jieshihuanhun"] = "借尸还魂",
  [":rfenghou__jieshihuanhun"] = "你可以将两张牌当一张基本牌或普通锦囊牌使用，但需满足：<br>"..
  "1.至少有一张牌与你上次的转化底牌名字相同；<br>2.至少有一个目标与你上次以此使用牌时不同。",
  ["rfenghou__shengshengbuxi"] = "生生不息",
  [":rfenghou__shengshengbuxi"] = "锁定技，你最后一张手牌具有“绥”标记。",
}

return extension
